/* ###################################################################
**  Copyright 2022 GSST, Inc.


**  Filename  : GSStm32F401_Init.c
**  Project     : TXBJ
**  Processor : STM32F401RCT6
**  Author     : GSST
**  Version    : V1.0
**  Compiler  : IAR C Compiler
**  Date/Time : 2022
**
** ###################################################################*/

/*******************************************************************************
 * Header
 ******************************************************************************/
 
#include "GSStm32F4_Includes.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define TIMER_SYSTICK_RELOAD_CNT 8400000 // 10Hz
#define TIMER_TIM4_RELOAD_CNT 84000 //  1ms: 84MHz / 2 / 42000 = 1kHz
#define TIMER_TIM5_RELOAD_CNT 8000 //  1ms: 84MHz / 2 / 42000 = 1kHz
//16MHz / 2 / 8000 = 1kHz
#define PWM_PRECHARGE_DUTY (TIMER_TIM1_RELOAD_CNT >> 1u)
#define TIMER_TIM2_RELOAD_CNT 28000 //  1ms: 84MHz / 2 / 42000 = 1kHz

#define EXTI15_10_ISR_PRI 0x01u // encZ
#define EXTI9_5_ISR_PRI 0x02u // hall
#define ADC_ISR_PRI 0x03u // ADC�ж�
#define TIM2_ISR_PRI 0x08u // 1ms high level
#define TIM4_ISR_PRI 0x0Au // 1ms low level
#define TIM3_ISR_PRI 0x09u // 1ms low level
#define TIM5_ISR_PRI 0x0Bu // 1ms high level

#define SYSTICK_ISR_PRI 0x0Fu  // Ҫ��ADC�ж����ȼ���
#define DMA3_ISR_PRI 0x05u

/*******************************************************************************
 * Variables
 ******************************************************************************/

_ADC_SAMPLES g_adcOrigDataTurnOn;
_ADC_SAMPLES g_adcOrigDataTurnOff;

/*******************************************************************************
 * Code
 ******************************************************************************/

// initialization

static void s_cpuClkInit(void)
{
    __VOLTAILE uint32_t l_rccRegStatus = 0;
    // ʹ���ⲿʱ�ӣ����ȴ��ⲿʱ�Ӿ���
    RCC->CR |= ((uint32_t)RCC_CR_HSEON);    // enable external high-spd clk
    l_rccRegStatus = RCC->CR & RCC_CR_HSERDY;   // waiting for the clk ready 
    while(!l_rccRegStatus){
        l_rccRegStatus = RCC->CR & RCC_CR_HSERDY;}  // һ����ʱ���麯�������ӣ�TBA

    // ����PLL 
    l_rccRegStatus = 0;
    l_rccRegStatus = RCC_PLLCFGR_PLLSRC_HSE; // HSEʱ����ΪPLL����ʱ��
    l_rccRegStatus |= 5 << 0U; // VCO In Freq = 8MHz / 5 = 1.6MHz
    l_rccRegStatus |= 210 << 6U; // VCO Out Freq = 1.6MHz x 210 = 336MHz
    l_rccRegStatus |= 1 << 16U; // Main PLL Out Freq = 336MHz / 2 = 168MHz
    l_rccRegStatus |= 7 << 24U; // USB/SDIO PLL Out Freq = 336MHz / 7 = 48MHz
    RCC->PLLCFGR = l_rccRegStatus;
    // // ʹ��PLL�����ȴ�PLL����
    RCC->CR |= RCC_CR_PLLON; // enable PLL
    l_rccRegStatus = RCC->CR & RCC_CR_PLLRDY;   // waiting for the clk ready 
    while(!l_rccRegStatus){
        l_rccRegStatus = RCC->CR & RCC_CR_PLLRDY;}  // һ����ʱ���麯�������ӣ�TBA    

    // // FLASH�ķ�����ʱ����
    // FLASH->ACR |= BIT1; // �����ȴ�״̬
    
    // ��������ʱ��,������ʱ���л�ΪPLL���
    RCC->DCKCFGR = 0; // ʹ�ó������ã���F103һ����
                                     // ע��:APB1�Ͻӵ�Timer������Ƶ�ʲ���42MHz������84MHz��
    l_rccRegStatus = 0;
    // l_rccRegStatus |= 2 << 21; // HSE ��MCO1 ,������
    l_rccRegStatus |= 0 << 4; // AHB Freq = PLL Out / 1; 168MHz
    l_rccRegStatus |= 0 << 13; // APB2 Freq = AHB Freq / 2; 84MHz
    l_rccRegStatus |= 4 << 10; // APB1 Freq = AHB Freq / 4; 42MHz
    l_rccRegStatus |= 2<< 0; // PLL��Ϊ��ʱ��
    RCC->CFGR = l_rccRegStatus;
    l_rccRegStatus = (RCC->CFGR & (0x3<<2)) >> 2;   
    while(2 != l_rccRegStatus){ // waiting for the switch ready 
        l_rccRegStatus = (RCC->CFGR & (0x3<<2)) >> 2;}

    // ����SysTick
    SysTick->LOAD  = (uint32_t)(TIMER_SYSTICK_RELOAD_CNT - 1u); // ����SysTick����
    SysTick->VAL = 0u; // load the systick counter value    
    NVIC_SetPriority(SysTick_IRQn, SYSTICK_ISR_PRI); // set priority for systick interrupt
    NVIC_EnableIRQ(SysTick_IRQn);
    SysTick->CTRL |= BIT2 | BIT1 | BIT0; // systick clk = HCLK, enable systick IRQ, enable systick timer
  
    // ����ʱ��ʹ��
    RCC->AHB1ENR = RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN
                                | RCC_AHB1ENR_DMA1EN | RCC_AHB1ENR_DMA2EN;
    RCC->APB1ENR = RCC_APB1ENR_TIM2EN  | RCC_APB1ENR_TIM4EN |RCC_APB1ENR_TIM2EN| RCC_APB1ENR_TIM3EN
                                | RCC_APB1ENR_TIM5EN | RCC_APB1ENR_I2C1EN | RCC_APB1ENR_USART2EN| RCC_APB1ENR_USART3EN;
    RCC->APB2ENR = RCC_APB2ENR_TIM1EN | RCC_APB2ENR_ADC1EN | RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_USART1EN|RCC_APB2ENR_USART6EN;                                
}

static void s_timer5Init(void)
{
    TIM5->CR1 = TIM_CR1_URS; // ֻ������Ų����ж�  
    TIM5->PSC = 1; // Ԥ��Ƶϵ��Ϊ2
    TIM5->ARR = TIMER_TIM5_RELOAD_CNT - 1;
    TIM5->DIER = TIM_DIER_UIE;
    TIM5->CR1 |= TIM_CR1_CEN; // enable Timer
    // TIM5->EGR = TIM_EGR_UG; // update
    // TIM5->SR &= ~TIM_SR_UIF; // clear interrupt flag
    NVIC_SetPriority(TIM5_IRQn, TIM5_ISR_PRI); // set priority for timer interrupt in NVIC
    NVIC_EnableIRQ(TIM5_IRQn); // enable interrupt in NVIC   
}

static void s_pinCfgInit(void)
{
    __VOLTAILE uint32_t l_gpioRegValue;

    //---------- GPIOA------------//
    // ����
    l_gpioRegValue = 0u;
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL0_Pos; // PA0 模拟ADC输入 通道0
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL1_Pos; // PA1 模拟张力输入 通道1
    l_gpioRegValue |= 7u << GPIO_AFRL_AFSEL2_Pos; // PA2 485_TX usart2 
    l_gpioRegValue |= 7u << GPIO_AFRL_AFSEL3_Pos; // PA3 485_RX usart2
    l_gpioRegValue |= 1u << GPIO_AFRL_AFSEL4_Pos; // PA4 485_SE
    l_gpioRegValue |= 1u << GPIO_AFRL_AFSEL5_Pos; // PA5 与PA6�?�?，用�?速输�?1 脉�?�信�? TIM2_CH1
    #ifdef GS_IS_NEW_BROAD
    l_gpioRegValue |= 2u << GPIO_AFRL_AFSEL6_Pos; // PA6 �?速输�?1 脉�?�信�? 
    #else
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL6_Pos; // PA6 �?速输�?1 脉�?�信�? 
    #endif // GS_IS_NEW_BROAD
    
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL7_Pos; // PA7 �?速输�?2 �?通输�?
    GPIOA->AFR[0] = l_gpioRegValue; 

    l_gpioRegValue = 0u;    
    l_gpioRegValue |= 1u << GPIO_AFRH_AFSEL8_Pos; //  PA8  TIM1_CH1
    l_gpioRegValue |= 1u << GPIO_AFRH_AFSEL9_Pos; //  PA9  TIM1_CH2
    l_gpioRegValue |= 1u << GPIO_AFRH_AFSEL10_Pos; // PA10 TIM1_CH3
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL11_Pos; // PA11 测试按钮 �?通输�?
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL12_Pos; // PA12 复位按钮 �?通输�?
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL13_Pos; // PA13 SWDIO
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL14_Pos; // PA14 SWCLK
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL15_Pos; // PA15 慢速输�? �?通输�?
    GPIOA->AFR[1] = l_gpioRegValue; 

    // ģʽ
    // 0 IN, 1 OUT, 2 FUNC, 3 ANA
    l_gpioRegValue = 0u;
    l_gpioRegValue |= 3u << GPIO_MODER_MODE0_Pos; // PA0   模拟ADC输入 通道0
    l_gpioRegValue |= 3u << GPIO_MODER_MODE1_Pos; // PA1   模拟张力输入 通道1
    l_gpioRegValue |= 2u << GPIO_MODER_MODE2_Pos; // PA2   485_TX usart2 
    l_gpioRegValue |= 2u << GPIO_MODER_MODE3_Pos; // PA3   485_RX usart2
    l_gpioRegValue |= 1u << GPIO_MODER_MODE4_Pos; // PA4   485_SE
    l_gpioRegValue |= 1u << GPIO_MODER_MODE5_Pos; // PA5   与PA6�?�?，用�?速输�?1 脉�?�信�? TIM2_CH1
    #ifdef GS_IS_NEW_BROAD
    l_gpioRegValue |= 2u << GPIO_MODER_MODE6_Pos; // PA6   �?速输�?1 脉�?�信�? 
    #else
    l_gpioRegValue |= 0u << GPIO_MODER_MODE6_Pos; // PA6   �?速输�?1 脉�?�信�? 
    #endif // GS_IS_NEW_BROAD
   
    l_gpioRegValue |= 0u << GPIO_MODER_MODE7_Pos; // PA7   �?速输�?2 �?通输�?
    l_gpioRegValue |= 2u << GPIO_MODER_MODE8_Pos; // PA8   TIM1_CH1
    l_gpioRegValue |= 2u << GPIO_MODER_MODE9_Pos; // PA9   TIM1_CH2    
    l_gpioRegValue |= 2u << GPIO_MODER_MODE10_Pos; // PA10 TIM1_CH3  
    l_gpioRegValue |= 0u << GPIO_MODER_MODE11_Pos; // PA11 测试按钮 �?通输�?
    l_gpioRegValue |= 0u << GPIO_MODER_MODE12_Pos; // PA12 复位按钮 �?通输�?
    l_gpioRegValue |= 2u << GPIO_MODER_MODE13_Pos; // PA13 SWDIO
    l_gpioRegValue |= 2u << GPIO_MODER_MODE14_Pos; // PA14 SWCLK
    l_gpioRegValue |= 1u << GPIO_MODER_MODE15_Pos; // PA15 慢速输�? �?通输�?
    GPIOA->MODER = l_gpioRegValue; 

    // ����ٶ�
    l_gpioRegValue = 0u;
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED0_Pos; // PA0   模拟ADC输入 通道0
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED1_Pos; // PA1   模拟张力输入 通道1
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED2_Pos; // PA2   485_TX usart2 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED3_Pos; // PA3   485_RX usart2
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED4_Pos; // PA4   485_SE
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED5_Pos; // PA5   与PA6�?�?，用�?速输�?1 脉�?�信�? TIM2_CH1
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED6_Pos; // PA6   �?速输�?1 脉�?�信�? 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED7_Pos; // PA7   �?速输�?2 �?通输�?
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED8_Pos; // PA8   TIM1_CH1
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED9_Pos; // PA9   TIM1_CH2
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED10_Pos; // PA10 TIM1_CH3
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED11_Pos; // PA11 USATR6 TX
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED12_Pos; // PA12 USATR6 RX
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED13_Pos; // PA13 SWDIO
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED14_Pos; // PA14 SWCLK
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED15_Pos; // PA15 慢速输�? �?通输�?
    GPIOA->OSPEEDR = l_gpioRegValue; 

    // ����
    GPIOA->OTYPER = 0u; // �������
    GPIOA->PUPDR = 0u; // no pullup, no pulldown
    GPIOA->ODR = 0u; // Ĭ�����0��

    //---------- GPIOB------------//
    l_gpioRegValue = 0u;
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL0_Pos; // PB0 高速输�? IO
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL1_Pos; // PB1 输入
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL2_Pos; // PB2 输入
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL3_Pos; // PB3 输入
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL4_Pos; // PB4 编码器A TIM3_CH3 飞线到PC8
    //PB5-7   HALL
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL5_Pos; // PB5 编码器B TIM3_CH4 飞线到PC9
    #ifdef GS_IS_NEW_BROAD
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL6_Pos; // PB6 输入
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL7_Pos; // PB7 制动 �?通输�?
    #else
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL6_Pos; // PB6 输入
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL7_Pos; // PB7 制动 �?通输�?
    #endif // GS_IS_NEW_BROAD

    GPIOB->AFR[0] = l_gpioRegValue; 

    l_gpioRegValue = 0u;    
    l_gpioRegValue |= 4u << GPIO_AFRH_AFSEL8_Pos; //  PB8  
    l_gpioRegValue |= 4u << GPIO_AFRH_AFSEL9_Pos; //  PB9  
    l_gpioRegValue |= 7u << GPIO_AFRH_AFSEL10_Pos; // PB10 motor_tx usart3
    l_gpioRegValue |= 7u << GPIO_AFRH_AFSEL11_Pos; // PB11 motor_rx usart3
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL12_Pos; // PB12 
    l_gpioRegValue |= 1u << GPIO_AFRH_AFSEL13_Pos; // PB13 
    l_gpioRegValue |= 1u << GPIO_AFRH_AFSEL14_Pos; // PB14 
    l_gpioRegValue |= 1u << GPIO_AFRH_AFSEL15_Pos; // PB15 
    GPIOB->AFR[1] = l_gpioRegValue; 

    // 0 IN, 1 OUT, 2 FUNC, 3 ANA
    l_gpioRegValue = 0u;
    l_gpioRegValue |= 1u << GPIO_MODER_MODE0_Pos;  // PB0 
    l_gpioRegValue |= 0u << GPIO_MODER_MODE1_Pos;  // PB1 
    l_gpioRegValue |= 0u << GPIO_MODER_MODE2_Pos;  // PB2 
    l_gpioRegValue |= 0u << GPIO_MODER_MODE3_Pos;  // PB3 
    l_gpioRegValue |= 0u << GPIO_MODER_MODE4_Pos;  // PB4 
    l_gpioRegValue |= 0u << GPIO_MODER_MODE5_Pos;  // PB5 
    #ifdef GS_IS_NEW_BROAD
    l_gpioRegValue |= 0u << GPIO_MODER_MODE6_Pos;  // PB6 
    l_gpioRegValue |= 0u << GPIO_MODER_MODE7_Pos;  // PB7 
    #else
    l_gpioRegValue |= 0u << GPIO_MODER_MODE6_Pos;  // PB6  输入
    l_gpioRegValue |= 1u << GPIO_MODER_MODE7_Pos;  // PB7  制动 �?通输�?
    #endif // GS_IS_NEW_BROAD

    l_gpioRegValue |= 0u << GPIO_MODER_MODE8_Pos;  // PB8 
    l_gpioRegValue |= 0u << GPIO_MODER_MODE9_Pos;  // PB9 
    l_gpioRegValue |= 2u << GPIO_MODER_MODE10_Pos; // PB10 motor_tx usart3
    l_gpioRegValue |= 2u << GPIO_MODER_MODE11_Pos; // PB11 motor_rx usart3
    l_gpioRegValue |= 0u << GPIO_MODER_MODE12_Pos; // PB12
    l_gpioRegValue |= 0u << GPIO_MODER_MODE13_Pos; // PB13
    l_gpioRegValue |= 0u << GPIO_MODER_MODE14_Pos; // PB14
    l_gpioRegValue |= 0u << GPIO_MODER_MODE15_Pos; // PB15
    GPIOB->MODER = l_gpioRegValue; 

    // ����ٶ�
    l_gpioRegValue = 0u;
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED0_Pos; // PB0 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED1_Pos; // PB1 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED2_Pos; // PB2 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED3_Pos; // PB3 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED4_Pos; // PB4  
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED5_Pos; // PB5  
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED6_Pos; // PB6 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED7_Pos; // PB7  
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED8_Pos; // PB8 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED9_Pos; // PB9 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED10_Pos;// PB10 motor_tx
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED11_Pos;// PB11 motor_rx
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED12_Pos;// PB12 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED13_Pos;// PB13 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED14_Pos;// PB14 
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED15_Pos;// PB15 
    GPIOB->OSPEEDR = l_gpioRegValue; 

    // ����
    GPIOB->OTYPER = 0; 
    GPIOB->PUPDR = 0u; // no pullup, no pulldown
    GPIOB->ODR = 0u; // Ĭ�����0��

    //---------- GPIOC------------//
    // ����
    l_gpioRegValue = 0u;
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL0_Pos; // PC0 模拟U电流 通道10
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL1_Pos; // PC1 模拟V电流 通道11
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL2_Pos; // PC2 模拟W电流 通道12
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL3_Pos; // PC3 慢速输�?2
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL4_Pos; // PC4 慢速输�?1
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL5_Pos; // PC5 输入
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL6_Pos; // PC6 输入
    l_gpioRegValue |= 0u << GPIO_AFRL_AFSEL7_Pos; // PC7 输入
    GPIOC->AFR[0] = l_gpioRegValue; 

    l_gpioRegValue = 0u;    
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL8_Pos;  // PC8  输入
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL9_Pos;  // PC9  输入
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL10_Pos; // PC10 编码器零�?
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL11_Pos; // PC11 编码�?5V使能
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL12_Pos; // PC12 15V使能
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL13_Pos; // PC13 输入
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL14_Pos; // PC14 输入
    l_gpioRegValue |= 0u << GPIO_AFRH_AFSEL15_Pos; // PC15 输入
    GPIOC->AFR[1] = l_gpioRegValue; 

    // 0 IN, 1 OUT, 2 FUNC, 3 ANA
    l_gpioRegValue = 0u;
    l_gpioRegValue |= 3u << GPIO_MODER_MODE0_Pos; // PC0 模拟U电流 通道10
    l_gpioRegValue |= 3u << GPIO_MODER_MODE1_Pos; // PC1 模拟V电流 通道11
    l_gpioRegValue |= 3u << GPIO_MODER_MODE2_Pos; // PC2 模拟W电流 通道12
    l_gpioRegValue |= 0u << GPIO_MODER_MODE3_Pos; // PC3 慢速输�?2
    l_gpioRegValue |= 0u << GPIO_MODER_MODE4_Pos; // PC4 慢速输�?1
    l_gpioRegValue |= 0u << GPIO_MODER_MODE5_Pos; // PC5 输入
    l_gpioRegValue |= 0u << GPIO_MODER_MODE6_Pos; // PC6 输入
    l_gpioRegValue |= 0u << GPIO_MODER_MODE7_Pos; // PC7 输入
    l_gpioRegValue |= 0u << GPIO_MODER_MODE8_Pos; // PC8  输入
    l_gpioRegValue |= 0u << GPIO_MODER_MODE9_Pos; // PC9  输入
    l_gpioRegValue |= 1u << GPIO_MODER_MODE10_Pos;// PC10 编码器零�?
    l_gpioRegValue |= 1u << GPIO_MODER_MODE11_Pos;// PC11 编码�?5V使能
    l_gpioRegValue |= 1u << GPIO_MODER_MODE12_Pos;// PC12 15V使能
    l_gpioRegValue |= 0u << GPIO_MODER_MODE13_Pos;// PC13 输入
    l_gpioRegValue |= 0u << GPIO_MODER_MODE14_Pos;// PC14 输入
    l_gpioRegValue |= 0u << GPIO_MODER_MODE15_Pos;// PC15 输入
    GPIOC->MODER = l_gpioRegValue; 

    // ����ٶ�
    l_gpioRegValue = 0u;
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED0_Pos; // PC0 模拟U电流 通道10
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED1_Pos; // PC1 模拟V电流 通道11
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED2_Pos; // PC2 模拟W电流 通道12
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED3_Pos; // PC3 慢速输�?2
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED4_Pos; // PC4 慢速输�?1
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED5_Pos; // PC5 输入
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED6_Pos; // PC6 输入
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED7_Pos; // PC7 输入
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED8_Pos; // PC8  输入
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED9_Pos; // PC9  输入
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED10_Pos;// PC10 编码器零�?
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED11_Pos;// PC11 编码�?5V使能
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED12_Pos;// PC12 15V使能
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED13_Pos;// PC13 输入
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED14_Pos;// PC14 输入
    l_gpioRegValue |= 3u << GPIO_OSPEEDR_OSPEED15_Pos;// PC15 输入
    GPIOC->OSPEEDR = l_gpioRegValue; 

    // ����
    GPIOC->OTYPER = 0u; // �������
    GPIOC->PUPDR = 0u; // no pullup, no pulldown
    GPIOC->ODR = 0u; // Ĭ�����0��    
}
static void s_uart3Init(uint16 l_parityEna, uint16 l_stopBits)
{
    USART3->SR = 0xC0; 
    USART3->CR1 = 0u;
    USART3->CR2 = 0u;
    USART3->CR3 = 0u;
        
    USART3->CR1 |= BIT13; // enable uart
    
    if(1 == l_parityEna)    // У��λ�趨
    {
        USART3->CR1 |= BIT12 | BIT10 | BIT9;
        
    }
    else if(2 == l_parityEna)
    {
        USART3->CR1 |= BIT12 | BIT10;
    }
    else{}

    if(2 == l_stopBits){    // ֹͣλ�趨
        USART3->CR2 |= BIT13;}    

    USART3->CR3 |= BIT8 | BIT7 | BIT6; // enable nRTS, Tx DMA, Rx DMA

    // 42MHz / 16 * 273.4375 = 9600 ���� 273 ����0.4375, 7->0x1117
    // 84MHz / 16 * 546.875 = 9600 ���� 546 ����0.875, 7->0x222E
    // 84MHz / 16 * 46.875 = 56000 ���� 46 ����0.875, 14->0x2EE  93.75  0x5DC
    // USART3->BRR = 0x208; // ���ò�����Ϊ19200bps
    #ifdef GS_IS_NEW_ARM
        USART3->BRR = 0x104; // ���ò�����Ϊ19200bps
    #else
        USART3->BRR = 0x208; // ���ò�����Ϊ19200bps
    #endif // GS_IS_NEW_ARM
    USART3->CR1 |= BIT2 | BIT3; // enable Tx and Rx
}


static void s_uart2Init(uint16 l_parityEna, uint16 l_stopBits)
{
    USART2->SR = 0xC0; // ���ǵ������������³�ʼ�����ձ���мĴ�����ʼ�����������? 
    USART2->CR1 = 0u;
    USART2->CR2 = 0u;
    USART2->CR3 = 0u;
        
    USART2->CR1 |= BIT13; // enable uart
    
    if(1 == l_parityEna)    // У��λ�趨
    {
        USART2->CR1 |= BIT12 | BIT10 | BIT9;
        
    }
    else if(2 == l_parityEna)
    {
        USART2->CR1 |= BIT12 | BIT10;
    }
    else{}

    if(2 == l_stopBits){    // ֹͣλ�趨
        USART2->CR2 |= BIT13;}    

    USART2->CR3 |= BIT8 | BIT7 | BIT6; // enable nRTS, Tx DMA, Rx DMA

    // 42MHz / 16 * 273.4375 = 9600 ���� 273 ����0.4375, 7->0x1117
    // 84MHz / 16 * 546.875 = 9600 ���� 546 ����0.875, 7->0x222E
    // 84MHz / 16 * 46.875 = 56000 ���� 46 ����0.875, 14->0x2EE  93.75  0x5DC
    // 57600    0x208
    
    #ifdef GS_IS_NEW_ARM
        USART2->BRR = 0x104; // ���ò�����Ϊ19200bps
    #else
        USART2->BRR = 0x208; // ���ò�����Ϊ19200bps
    #endif // GS_IS_NEW_ARM
    USART2->CR1 |= BIT2 | BIT3; // enable Tx and Rx
}

static void s_dmaInit(void)
{

    //  USART3_RX
    DMA1_Stream1->NDTR = GS_CMU_IN_BUFF_LEN; 
    DMA1_Stream1->PAR = (uint32_t)(&(USART3->DR)); 
    #ifdef GS_IS_NEW_ARM
    DMA1_Stream1->M0AR = (uint32_t)(&g_nanoCmuData.d_inData.d_data); 
    DMA1_Stream1->M1AR = (uint32_t)(&g_nanoCmuData.d_inData.d_data); 
    #else
    DMA1_Stream1->M0AR = (uint32_t)(&g_motorCmuData.d_motorInData.d_data); 
    DMA1_Stream1->M1AR = (uint32_t)(&g_motorCmuData.d_motorInData.d_data); 
    #endif // GS_IS_NEW_ARM
    DMA1_Stream1->CR = (4u << 25) 
                      | (1u << 16)  
                      | (0u << 13) 
                      | (0u << 11) 
                      | DMA_SxCR_MINC //
                      | DMA_SxCR_CIRC 
                      | (0u << 6) // 
                      | DMA_SxCR_EN; //  
    //  USART2_RX
    DMA1_Stream5->NDTR = GS_CMU_IN_BUFF_LEN; 
    DMA1_Stream5->PAR = (uint32_t)(&(USART2->DR)); 
    #ifdef GS_IS_NEW_ARM
    DMA1_Stream5->M0AR = (uint32_t)(&g_motorCmuData.d_motorInData.d_data); 
    DMA1_Stream5->M1AR = (uint32_t)(&g_motorCmuData.d_motorInData.d_data); 
    #else
    DMA1_Stream5->M0AR = (uint32_t)(&g_nanoCmuData.d_inData.d_data); 
    DMA1_Stream5->M1AR = (uint32_t)(&g_nanoCmuData.d_inData.d_data); 
    #endif // GS_IS_NEW_ARM
    
    DMA1_Stream5->CR = (4u << 25) 
                      | (1u << 16)  
                      | (0u << 13) 
                      | (0u << 11) 
                      | DMA_SxCR_MINC //
                      | DMA_SxCR_CIRC 
                      | (0u << 6) // ���赽memory
                      | DMA_SxCR_EN; // ����ͨ�� // �����ж�    

    // USART2_TX
    DMA1_Stream6->NDTR = 0; // tx��������������Ŀ
    DMA1_Stream6->PAR = (uint32_t)(&(USART2->DR)); // ������?

    #ifdef GS_IS_NEW_ARM
    DMA1_Stream6->M0AR = (uint32_t)(&g_motorCmuData.d_motorInData.d_data); // �洢����ַ
    DMA1_Stream6->M1AR = (uint32_t)(&g_motorCmuData.d_motorInData.d_data); // �洢����ַ
    #else
    DMA1_Stream6->M0AR = (uint32_t)(&g_nanoCmuData.d_inData.d_data); // �洢����ַ
    DMA1_Stream6->M1AR = (uint32_t)(&g_nanoCmuData.d_inData.d_data); // �洢����ַ    
    #endif // GS_IS_NEW_ARM
    DMA1_Stream6->CR = (4u << 25) // CH4
                      | (1u << 16) 
                      | (0u << 13) 
                      | (0u << 11) 
                      | DMA_SxCR_MINC 
                      | (1u << 6) 
                        | DMA_SxCR_TCIE; 
        // USART3_TX
    DMA1_Stream3->NDTR = 0; // tx��������������Ŀ
    DMA1_Stream3->PAR = (uint32_t)(&(USART3->DR)); // ������?

    DMA1_Stream3->M0AR = (uint32_t)(&g_nanoCmuData.d_inData.d_data); // �洢����ַ
    DMA1_Stream3->M1AR = (uint32_t)(&g_nanoCmuData.d_inData.d_data); // �洢����ַ

    DMA1_Stream3->CR = (4u << 25) // CH4
                      | (1u << 16) 
                      | (0u << 13) 
                      | (0u << 11) 
                      | DMA_SxCR_MINC 
                      | (1u << 6) 
                        | DMA_SxCR_TCIE; 
            
    DMA1->HIFCR = DMA_HIFCR_CTCIF6||DMA_LIFCR_CFEIF3; // ����жϱ�־�?
    NVIC_SetPriority(DMA1_Stream6_IRQn, DMA3_ISR_PRI); // set priority for the interrupt in NVIC
    NVIC_EnableIRQ(DMA1_Stream6_IRQn); // enable interrupt in NVIC     
    NVIC_SetPriority(DMA1_Stream3_IRQn, DMA3_ISR_PRI); // set priority for the interrupt in NVIC
    NVIC_EnableIRQ(DMA1_Stream3_IRQn); // enable interrupt in NVIC     
    //g_exCmuData.d_isSend = GS_FALSE;                                                       
}

static void s_timer2Init(void)
{
    TIM2->CR1 = TIM_CR1_URS; // ֻ������Ų����ж�  
    TIM2->PSC = 1; // Ԥ��Ƶϵ��Ϊ2
    TIM2->ARR = TIMER_TIM2_RELOAD_CNT - 1;
    TIM2->DIER = TIM_DIER_UIE; // enable interrupt
    TIM2->CR1 |= TIM_CR1_CEN; // enable Timer
    TIM2->EGR = TIM_EGR_UG; // update
    TIM2->SR &= ~TIM_SR_UIF; // clear interrupt flag
    NVIC_SetPriority(TIM2_IRQn, TIM2_ISR_PRI); // set priority for timer interrupt in NVIC
    NVIC_EnableIRQ(TIM2_IRQn); // enable interrupt in NVIC   
}
void g_sysInit(void){
    s_cpuClkInit(); // ϵͳʱ�����ã��ⲿʱ��ʹ��
    s_pinCfgInit();
    g_usDelay(30000);
    s_timer5Init();
    s_timer2Init();
    s_uart2Init(0u, 1u);
    s_uart3Init(0u, 1u);
    s_dmaInit();


   
    //s_pinCfgInit(); // IO ����

}
